#region Usings

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Castle.ActiveRecord;
using log4net;
using Karma.Framework.Core.Utils;

#endregion

namespace Karma.Framework.Core.Repository.Configuration
{
    public class RepositoryConfiguration
    {
        private static ILog LOG = LogManager.GetLogger(typeof(RepositoryConfiguration).Name);

        private static IDictionary<string, string[]> _uniqueKeys;

        private static Type[] _entities;

        public static Type[] Entities
        {
            get { return _entities; }
        }

        public static void Initialize()
        {
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug("Configuring Repository entities");
            }
            _uniqueKeys = new Dictionary<string, string[]>();
            foreach (var type in ActiveRecordConfiguration.Entities.Values)
            {
                var uks = (from p in type.GetProperties(BindingFlags.FlattenHierarchy |
                                                        BindingFlags.Public | BindingFlags.Instance)
                           let atts = p.GetCustomAttributes(true)
                           from att in atts
                           where typeof (PropertyAttribute).IsAssignableFrom(att.GetType())
                                 && ((PropertyAttribute) att).Unique
                           select p.Name).ToArray();
                if (uks != null && uks.Length > 0)
                {
                    _uniqueKeys.Add(type.FullName, uks);
                }
            }
            _entities = ActiveRecordConfiguration.Entities.Values.ToArray();
            if (LOG.IsDebugEnabled)
            {
                foreach (var key in _uniqueKeys.Keys)
                {
                    LOG.Debug(string.Format("UniqueKeys for entity {0}: {1}", key, _uniqueKeys[key].ItemsToString()));
                }
            }
        }

        public static string[] GetUniqueKeys(Type t)
        {
            return _uniqueKeys.ContainsKey(t.FullName) ? _uniqueKeys[t.FullName] : new string[] {};
        }
    }
}